﻿using System;
using System.Collections.Generic;
using System.Text;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.Metadata.Entity.DataModel;
using T.FAS.Runtime.StateMachine.SPI;

namespace T.FAS.Runtime.StateMachine.Engine
{
    class ExpressionRuleProcess : IRuleProcess
    {
        public const string CSTKEY = "FAS.Expression.Rule";
        private const string contextName = "FASContext";
        public string Key => CSTKEY;

        public string Description => "必填";

        public List<ParamInfo> NeedParamInfo =>  null;

        public bool IsPreCheck => false;

        /// <summary>
        /// 表达式规则校验
        /// </summary>
        /// <param name="record"></param>
        /// <param name="state"></param>
        /// <param name="rule"></param>
        /// <param name="metadata"></param>
        /// <param name="failReason"></param>
        /// <returns></returns>
        public bool Check(TRecord record, TState state, TRule rule, StateMachineMetadata metadata, StringBuilder failReason)
        {
            if (record == null || state == null || rule == null)
                return true;

            bool checkResult = true;
            var i18NDecription = I18NUtil.GetTranslatedText(rule.GetRefSchemaExpr(metadata), rule.Description);
            var errorPrefix = i18NDecription;
            Dictionary<string, object> expParam = new Dictionary<string, object>();
            var fasContext = new FASContext
            {
                CurrentRecord = record,
                PKColumnName = record.PKColumnName
            };

            foreach (var ruleContent in rule.RuleContents)
            {
                var result = Expression.Service.ExprService.GetInstance.Execute(ruleContent.RuleInfoJson, fasContext, expParam);
                if (result.State == Expression.Entity.ResultState.Fail)
                {
                    failReason.AppendLine(string.Format(CommonStringClass.ExpressionRuleProcess_Check, errorPrefix, result.ErrMsg));
                    checkResult = false;
                }
                else
                {
                    checkResult = Convert.ToBoolean(result.Result);
                    if (checkResult == false)
                    {
                        failReason.AppendLine(errorPrefix);
                    }
                }
            }
            return checkResult;
        }
    }
}
